/***********************************************************************************
Copy right:     Coffee Tech.
Author:         gaoxingda
Date:           2022.2.11
Description:    共享内存传递节点信息
***********************************************************************************/
#include "head.h"
#include <shmem.h>
#include <stdlib.h>

#define MAX 5

static struct shm_param para;
/*
作者：高兴达
时间：2022年2月11日
功能：创建共享内存
 */
struct std_node *shm(char *s)
{
    //共享内存的创建
    int ret = -1;
    ret = shm_init(&para, s, sizeof(struct std_node) * MAX);
    if (ret < 0)
    {
        return NULL;
    }
    //获取共享内存首地址
    struct std_node *addr = shm_getaddr(&para);
    if (addr == NULL)
    {
        return NULL;
    }
    return addr;
}

/*
作者：高兴达
时间：2022年2月12日
功能：读取内存并完成序列化
 */
cJSON *read_shm_all(struct std_node *m0,struct std_node *modbus)
{
    int number = 0;
    cJSON *root = cJSON_CreateObject(); //根节点
    cJSON *item = cJSON_CreateArray();  //创建一个数组
   
    cJSON *next_M0[15];
    cJSON *next_Modbus[15];

    cJSON_AddItemToObject(root, "type", cJSON_CreateNumber(1)); //1,采集指令
    cJSON_AddItemToObject(root, "result", cJSON_CreateNumber(0)); //成功返回0,失败返回1

    for (int i = 0; i < M0_NUMBER; i++) //序列化
    {
        next_M0[i] = cJSON_CreateObject();
        cJSON *key = cJSON_CreateNumber(m0[i].key);
        cJSON_AddItemToObject(next_M0[i], "key", key); //节点号

        if(i < 2)
        {
            char ch[20] = {0};
            sprintf(ch,"%.2f",m0[i].new_val.f_val);

            cJSON *ke = cJSON_CreateString(ch);
            cJSON_AddItemToObject(next_M0[i], "val", ke); //节点号
        }
        else if(i == 2)
        {
            char ch[20] = {0};
            sprintf(ch,"%d",m0[i].new_val.i_val);

            cJSON *ke = cJSON_CreateString(ch);
            cJSON_AddItemToObject(next_M0[i], "val", ke); //节点号
        }

        cJSON_AddItemToArray(item, next_M0[i]); //添加到数组中
    }

    for (int i = 0; i < MODBUS_NUMBER; i++) //序列化modbus
    {
        next_Modbus[i] = cJSON_CreateObject();
        cJSON *key = cJSON_CreateNumber(modbus[i].key);
        cJSON_AddItemToObject(next_Modbus[i], "key", key); //节点号

            char ch[20] = {0};
            sprintf(ch,"%.2f",modbus[i].new_val.f_val);

            cJSON *ke = cJSON_CreateString(ch);
            cJSON_AddItemToObject(next_Modbus[i], "val", ke); //节点号

        cJSON_AddItemToArray(item, next_Modbus[i]); //添加到数组中
    }
    cJSON_AddItemToObject(root, "data", item); //将数组添加到根目录

    return root;
}

/*
作者：高兴达
时间：2022年2月14日
函数功能：实现变化上报
 */
void change_up(struct std_node *m0,struct std_node *modbus)
{
    int number = 0;
    cJSON *root = cJSON_CreateObject(); //根节点
    cJSON *item = cJSON_CreateArray();  //创建一个数组
    cJSON *next_M0[15];
    cJSON *next_Modbus[15];

    int M0 = 0;
    int Modbus = 0;

    for (int i = 0; i < M0_NUMBER; i++) //判断M0节点是否变化，并将变化的节点数据进行序列化
    {
  
        if(m0[i].new_val.i_val != m0[i].old_val.i_val)
        {
            M0 = 1;
            next_M0[i] = cJSON_CreateObject();
            cJSON *key = cJSON_CreateNumber(m0[i].key);
            cJSON_AddItemToObject(next_M0[i], "key", key); //节点号
            if(i < 2)
            {
                char ch[20] = {0};
                sprintf(ch,"%.2f",m0[i].new_val.f_val);

                cJSON *ke = cJSON_CreateString(ch);
                cJSON_AddItemToObject(next_M0[i], "val", ke); //节点号 
               
            }
            else if(i == 2)
            {
                char ch[20] = {0};
                sprintf(ch,"%d",m0[i].new_val.i_val);

                cJSON *ke = cJSON_CreateString(ch);
                cJSON_AddItemToObject(next_M0[i], "val", ke); //节点号  
            }
            cJSON_AddItemToArray(item, next_M0[i]); //添加到数组中
        }
    }

    for (int i = 0; i < MODBUS_NUMBER; i++) //判断M0节点是否变化，并将变化的节点数据进行序列化
    {
  
        if(modbus[i].new_val.f_val != modbus[i].old_val.f_val)
        {
            Modbus = 1;
          
            // printf("new = %.2f\n",modbus[i].new_val.f_val);
            // printf("old = %.2f\n",modbus[i].old_val.f_val);
            next_Modbus[i] = cJSON_CreateObject();
            cJSON *key = cJSON_CreateNumber(modbus[i].key);
            cJSON_AddItemToObject(next_Modbus[i], "key", key); //节点号


                char ch[20] = {0};
                sprintf(ch,"%.2f",modbus[i].new_val.f_val);

                cJSON *ke = cJSON_CreateString(ch);
                cJSON_AddItemToObject(next_Modbus[i], "val", ke); 

            cJSON_AddItemToArray(item, next_Modbus[i]); //添加到数组中
        }
    }

    cJSON_AddItemToObject(root, "type", cJSON_CreateNumber(1)); //1,采集指令
    cJSON_AddItemToObject(root, "result", cJSON_CreateNumber(0)); //成功返回0,失败返回1

    if(M0 == 1 || Modbus == 1)
    {
        cJSON_AddItemToObject(root, "data", item); 
        mqtt_to_client(TOPIC_DATA_UP,cJSON_Print(root));  
    }

    sleep(1);

}
